package com.yjd.bi.etl.user.service;

import com.yjd.bi.etl.comm.BaseService;
import com.yjd.bi.etl.comm.Constants;
import com.yjd.bi.etl.sql.UserSqlConstants;
import com.yjd.bi.etl.sql.enums.OrderChannel;
import com.yjd.bi.report.model.BiDatabaseInfoModel;
import com.yjd.bi.report.util.BiUtil;
import com.yjd.comm.borrow.enums.InvestChannelEnum;
import com.yjd.comm.enums.UserEnums;
import com.yjd.comm.util.DateUtil;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.Calendar;

@Component("userPlatformDataStatisticService")
public class UserPlatformDataStatisticService extends BaseService {

	private static final int DAYOFSECOND = 86400;
	private static final String PC_RECH_CHANNEL = "pc";// 充值渠道:医界贷主站
	private static final String IOS_RECH_CHANNEL = "ios";// 充值渠道:ios
	private static final String ANDRIOD_RECH_CHANNEL = "android";// 充值渠道:android
	private static final String WAP_RECH_CHANNEL = "wap";// 充值渠道:医界贷wap微站
	private static final int NONE_USER_CHANNEL = -1; // 单纯的为insert sql中的in中填值

	public void statistic(int statistic_type) throws Exception {
		BiDatabaseInfoModel model = this.getBiDatabaseInfoModel();
		JdbcTemplate jt = BiUtil.getJdbcTemplate(model);
		long maxDate = 0l;
		// 统计历史数据
		switch (statistic_type) {
		case 1:
			//每次统计清空前30天数据，重新跑
			jt.update(UserSqlConstants.DELETE_PC_STATISTIC);
			maxDate = jt.queryForInt(UserSqlConstants.GET_MAX_PC_USER_DATA);
			break;
		case 2:
			//每次统计清空前30天数据，重新跑
			jt.update(UserSqlConstants.DELETE_APP_STATISTIC);
			maxDate = jt.queryForInt(UserSqlConstants.GET_MAX_APP_USER_DATA);
			break;
		case 3:
			//每次统计清空前30天数据，重新跑
			jt.update(UserSqlConstants.DELETE_WAP_STATISTIC);
			maxDate = jt.queryForInt(UserSqlConstants.GET_MAX_WAP_USER_DATA);
			break;
		}

		if (maxDate == 0) {
			// 没有统计过，取网站上线运营的第一天 平台上线时间（2013年12月21日00：00：00）
			maxDate = Constants.INITIALIZATION_TIME;
		} else {
			maxDate = DateUtil.dateStringToTimestamp(maxDate + "",
					DateUtil.PATTERN_yyyyMMdd) + DAYOFSECOND;
		}

		// 获取当天的0点的时间戳
		Calendar todayStart = Calendar.getInstance();
		todayStart.set(Calendar.HOUR_OF_DAY, 0);
		todayStart.set(Calendar.MINUTE, 0);
		todayStart.set(Calendar.SECOND, 0);
		todayStart.set(Calendar.MILLISECOND, 0);
		long todayTime = todayStart.getTime().getTime() / 1000L;

		while (maxDate < todayTime) {
			// 统计前一天的用户数据
			switch (statistic_type) {
			case 1:
				statisticPCData(maxDate, jt);
				break;
			case 2:
				statisticAPPData(maxDate, jt);
				break;
			case 3:
				statisticWAPData(maxDate, jt);
				break;
			}
			maxDate += DAYOFSECOND;// 加一天和当前时间比较，如果小于当前时间则继续统计

		}
	}

	/**
	 * 统计PC的数据
	 * @param maxDate
	 * @param jt
	 */
	private void statisticPCData(long maxDate, JdbcTemplate jt) {
		long beginDate = maxDate;
		long endDate = beginDate + DAYOFSECOND - 1;
		Long staticsDate = Long.parseLong(DateUtil.timestampToDateString(
				beginDate, DateUtil.PATTERN_yyyyMMdd));

		// PC端注册人数
		int register_count_pc = jt.queryForObject(UserSqlConstants.GET_REGISTER_USER_COUNT_MORE, 
				new Object[] {beginDate, endDate, UserEnums.Channel.PC.getCode(),UserEnums.Channel.NONE.getCode() }, Integer.class);
		//PC端登录人数
		int login_count_pc = jt.queryForObject(UserSqlConstants.GET_LOGIN_USER_COUNT, 
				new Object[] {beginDate, endDate, UserEnums.Channel.PC.getCode()}, Integer.class);
		//PC端充值用户数
		int rechagre_count_pc = jt.queryForObject(UserSqlConstants.get_charge_count(OrderChannel.PC_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Integer.class);
		//PC端投资用户数
		int invest_count_pc = jt.queryForObject(UserSqlConstants.GET_INVEST_COUNT, 
				new Object[] { InvestChannelEnum.PIC.getValue(),beginDate, endDate,InvestChannelEnum.PIC.getValue(),beginDate, endDate}, Integer.class);
		//PC端充值金额
		double recharge_price_pc = jt.queryForObject(UserSqlConstants.get_charge_price(OrderChannel.PC_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Double.class);
		//PC端投资金额
		double invest_price_pc = jt.queryForObject(UserSqlConstants.GET_INVEST_PRICE, 
				new Object[] { InvestChannelEnum.PIC.getValue(),beginDate, endDate, InvestChannelEnum.PIC.getValue(),beginDate, endDate}, Double.class);
		//PC端投资项目金额
		double borrow_price_pc = jt.queryForObject(UserSqlConstants.GET_BORROE_PRICE, 
				new Object[] { InvestChannelEnum.PIC.getValue(),beginDate, endDate}, Double.class);
		//PC端债权转让金额
		double creditor_transfer_price_pc = jt.queryForObject(UserSqlConstants.GET_CREDITOR_TRANSFER_PRICE, 
				new Object[] { UserEnums.Channel.PC.getCode(),beginDate, endDate}, Double.class);
		// PC端首次充值人数
		int first_rech_amount = jt.queryForObject(UserSqlConstants.get_first_charge_count(OrderChannel.PC_RECH_CHANNEL),
				new Object[] { beginDate, endDate }, Integer.class);
		// PC端首次投资人数
		int first_invest_amount = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT,
				new Object[] { UserEnums.Channel.PC.getCode(),UserEnums.Channel.NONE.getCode(),InvestChannelEnum.PIC.getValue(), beginDate, endDate },Integer.class);

		// PC端首次充值人数(不区分注册客户端)
		int first_rech_amount_all= jt.queryForObject(UserSqlConstants.get_first_charge_count_all(OrderChannel.PC_RECH_CHANNEL),
				new Object[] { beginDate, endDate }, Integer.class);
		// PC端首次投资人数(不区分注册客户端)
		int first_invest_amount_all = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT_ALL,
				new Object[] {InvestChannelEnum.PIC.getValue(), beginDate, endDate },Integer.class);

		try {
			jt.update(UserSqlConstants.INSERT_PC_USER_DATA, staticsDate,register_count_pc,rechagre_count_pc,invest_count_pc
					,recharge_price_pc,invest_price_pc, first_rech_amount, first_invest_amount,login_count_pc,borrow_price_pc,creditor_transfer_price_pc,first_rech_amount_all,first_invest_amount_all);
		} catch (Exception e) {
			logger.info("批量处理插入失败，处理sql:"
					+ UserSqlConstants.INSERT_PC_USER_DATA + "处理数据:"
					+ beginDate + "错误信息:" + e);
		}
	}

	private void statisticAPPData(long maxDate, JdbcTemplate jt) {
		long beginDate = maxDate;
		long endDate = beginDate + DAYOFSECOND - 1;
		Long staticsDate = Long.parseLong(DateUtil.timestampToDateString(
				beginDate, DateUtil.PATTERN_yyyyMMdd));

		// IOS端注册人数
		int register_count_ios = jt.queryForObject(UserSqlConstants.GET_REGISTER_USER_COUNT,
				new Object[] {beginDate, endDate, UserEnums.Channel.IOS.getCode() },Integer.class);

		// IOS端首次充值人数
		int ios_first_rech_amount = jt.queryForObject(UserSqlConstants.get_first_charge_count(OrderChannel.IOS_RECH_CHANNEL),
				new Object[] {beginDate, endDate }, Integer.class);

		// IOS端首次投资人数
		int ios_first_invest_amount = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT, 
				new Object[] {UserEnums.Channel.IOS.getCode(), NONE_USER_CHANNEL,InvestChannelEnum.IOS.getValue(), beginDate, endDate },Integer.class);
		
		// IOS端首次充值人数(不区分注册端)
		int ios_first_rech_amount_all = jt.queryForObject(UserSqlConstants.get_first_charge_count_all(OrderChannel.IOS_RECH_CHANNEL),
				new Object[] {beginDate, endDate }, Integer.class);

		// IOS端首次投资人数(不区分注册端)
		int ios_first_invest_amount_all = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT_ALL, 
				new Object[] {InvestChannelEnum.IOS.getValue(), beginDate, endDate },Integer.class);
		
		//IOS端登录人数
		int login_count_ios = jt.queryForObject(UserSqlConstants.GET_LOGIN_USER_COUNT, 
				new Object[] {beginDate, endDate, UserEnums.Channel.IOS.getCode()}, Integer.class);
		//IOS端充值用户数
		int rechagre_count_ios = jt.queryForObject(UserSqlConstants.get_charge_count(OrderChannel.IOS_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Integer.class);
		//IOS端投资用户数
		int invest_count_ios = jt.queryForObject(UserSqlConstants.GET_INVEST_COUNT, 
				new Object[] { InvestChannelEnum.IOS.getValue(),beginDate, endDate,InvestChannelEnum.IOS.getValue(),beginDate, endDate}, Integer.class);
		//IOS端充值金额
		double recharge_price_ios = jt.queryForObject(UserSqlConstants.get_charge_price(OrderChannel.IOS_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Double.class);
		//IOS端投资金额
		double invest_price_ios = jt.queryForObject(UserSqlConstants.GET_INVEST_PRICE, 
				new Object[] { InvestChannelEnum.IOS.getValue(),beginDate, endDate, InvestChannelEnum.IOS.getValue(),beginDate, endDate}, Double.class);
		//IOS端投资项目金额
		double borrow_price_ios = jt.queryForObject(UserSqlConstants.GET_BORROE_PRICE, 
				new Object[] { InvestChannelEnum.IOS.getValue(),beginDate, endDate}, Double.class);
		//IOS端债权转让金额
		double creditor_transfer_price_ios = jt.queryForObject(UserSqlConstants.GET_CREDITOR_TRANSFER_PRICE, 
				new Object[] { UserEnums.Channel.IOS.getCode(),beginDate, endDate}, Double.class);

		try {
			jt.update(UserSqlConstants.INSERT_APP_USER_DATA, staticsDate,register_count_ios,rechagre_count_ios,
					invest_count_ios,recharge_price_ios,invest_price_ios,ios_first_rech_amount, ios_first_invest_amount,
					login_count_ios,borrow_price_ios,creditor_transfer_price_ios, InvestChannelEnum.IOS.getValue(),ios_first_rech_amount_all,ios_first_invest_amount_all);
		} catch (Exception e) {
			logger.info("批量处理插入失败，处理sql:"
					+ UserSqlConstants.INSERT_APP_USER_DATA + "处理数据:"
					+ beginDate + "错误信息:" + e);
		}

		// ANDROID端注册人数
		int register_count_android = jt.queryForObject(UserSqlConstants.GET_REGISTER_USER_COUNT,
				new Object[] { beginDate, endDate,UserEnums.Channel.ANDROID.getCode() }, Integer.class);

		// ANDROID端首次充值人数
		int android_first_rech_amount = jt.queryForObject(UserSqlConstants.get_first_charge_count(OrderChannel.ANDRIOD_RECH_CHANNEL),
				new Object[] {beginDate, endDate },Integer.class);

		// ANDROID端首次投资人数
		int android_first_invest_amount = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT, 
				new Object[] {UserEnums.Channel.ANDROID.getCode(), NONE_USER_CHANNEL,InvestChannelEnum.ANDROID.getValue(), beginDate,endDate }, Integer.class);
		
		// ANDROID端首次充值人数(不区分客户端)
		int android_first_rech_amount_all = jt.queryForObject(UserSqlConstants.get_first_charge_count_all(OrderChannel.ANDRIOD_RECH_CHANNEL),
				new Object[] {beginDate, endDate },Integer.class);

		// ANDROID端首次投资人数(不区分客户端)
		int android_first_invest_amount_all = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT_ALL, 
				new Object[] {InvestChannelEnum.ANDROID.getValue(), beginDate,endDate }, Integer.class);
		
		
		//ANDROID端登录人数
		int login_count_android = jt.queryForObject(UserSqlConstants.GET_LOGIN_USER_COUNT, 
				new Object[] {beginDate, endDate, UserEnums.Channel.ANDROID.getCode()}, Integer.class);
		//ANDROID端充值用户数
		int rechagre_count_android = jt.queryForObject(UserSqlConstants.get_charge_count(OrderChannel.ANDRIOD_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Integer.class);
		//ANDROID端投资用户数
		int invest_count_android = jt.queryForObject(UserSqlConstants.GET_INVEST_COUNT, 
				new Object[] { InvestChannelEnum.ANDROID.getValue(),beginDate, endDate,InvestChannelEnum.ANDROID.getValue(),beginDate, endDate}, Integer.class);
		//ANDROID端充值金额
		double recharge_price_android = jt.queryForObject(UserSqlConstants.get_charge_price(OrderChannel.ANDRIOD_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Double.class);
		//ANDROID端投资金额
		double invest_price_android = jt.queryForObject(UserSqlConstants.GET_INVEST_PRICE, 
				new Object[] { InvestChannelEnum.ANDROID.getValue(),beginDate, endDate, InvestChannelEnum.ANDROID.getValue(),beginDate, endDate}, Double.class);
		//ANDROID端投资项目金额
		double borrow_price_android = jt.queryForObject(UserSqlConstants.GET_BORROE_PRICE, 
				new Object[] { InvestChannelEnum.ANDROID.getValue(),beginDate, endDate}, Double.class);
		//ANDROID端债权转让金额
		double creditor_transfer_price_android = jt.queryForObject(UserSqlConstants.GET_CREDITOR_TRANSFER_PRICE, 
				new Object[] { UserEnums.Channel.ANDROID.getCode(),beginDate, endDate}, Double.class);

		try {
			jt.update(UserSqlConstants.INSERT_APP_USER_DATA, staticsDate,register_count_android,rechagre_count_android,
					invest_count_android,recharge_price_android,invest_price_android,android_first_rech_amount, android_first_invest_amount,
					login_count_android,borrow_price_android,creditor_transfer_price_android, InvestChannelEnum.ANDROID.getValue(),android_first_rech_amount_all,android_first_invest_amount_all);
		} catch (Exception e) {
			logger.info("批量处理插入失败，处理sql:"
					+ UserSqlConstants.INSERT_APP_USER_DATA + "处理数据:"
					+ beginDate + "错误信息:" + e);
		}
	}

	private void statisticWAPData(long maxDate, JdbcTemplate jt) {
		long beginDate = maxDate;
		long endDate = beginDate + DAYOFSECOND - 1;
		Long staticsDate = Long.parseLong(DateUtil.timestampToDateString(
				beginDate, DateUtil.PATTERN_yyyyMMdd));

		// WAP端注册人数
		int register_count_wap = jt.queryForObject(UserSqlConstants.GET_REGISTER_USER_COUNT, 
				new Object[] {beginDate, endDate, UserEnums.Channel.WAP.getCode() },Integer.class);

		// WAP端首次充值人数
		int wap_first_rech_amount = jt.queryForObject(UserSqlConstants.get_first_charge_count(OrderChannel.WAP_RECH_CHANNEL),
				new Object[] {beginDate, endDate }, Integer.class);

		// WAP端首次投资人数
		int wap_first_invest_amount = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT,
				new Object[] { UserEnums.Channel.WAP.getCode(),NONE_USER_CHANNEL, InvestChannelEnum.WAP.getValue(),beginDate, endDate }, Integer.class);
		
		// WAP端首次充值人数(不区分注册端)
		int wap_first_rech_amount_all= jt.queryForObject(UserSqlConstants.get_first_charge_count_all(OrderChannel.WAP_RECH_CHANNEL),
				new Object[] {beginDate, endDate }, Integer.class);

		// WAP端首次投资人数(不区分注册端)
		int wap_first_invest_amount_all = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT_ALL,
				new Object[] { InvestChannelEnum.WAP.getValue(),beginDate, endDate }, Integer.class);
		
		//WAP端登录人数
		int login_count_wap = jt.queryForObject(UserSqlConstants.GET_LOGIN_USER_COUNT, 
				new Object[] {beginDate, endDate, UserEnums.Channel.WAP.getCode()}, Integer.class);
		//WAP端充值用户数
		int rechagre_count_wap = jt.queryForObject(UserSqlConstants.get_charge_count(OrderChannel.WAP_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Integer.class);
		//WAP端投资用户数
		int invest_count_wap = jt.queryForObject(UserSqlConstants.GET_INVEST_COUNT, 
				new Object[] { InvestChannelEnum.WAP.getValue(),beginDate, endDate,InvestChannelEnum.WAP.getValue(),beginDate, endDate}, Integer.class);
		//WAP端充值金额
		double recharge_price_wap = jt.queryForObject(UserSqlConstants.get_charge_price(OrderChannel.WAP_RECH_CHANNEL),
				new Object[] {beginDate, endDate}, Double.class);
		//WAP端投资金额
		double invest_price_wap = jt.queryForObject(UserSqlConstants.GET_INVEST_PRICE, 
				new Object[] { InvestChannelEnum.WAP.getValue(),beginDate, endDate, InvestChannelEnum.WAP.getValue(),beginDate, endDate}, Double.class);
		//WAP端投资项目金额
		double borrow_price_wap = jt.queryForObject(UserSqlConstants.GET_BORROE_PRICE, 
				new Object[] { InvestChannelEnum.WAP.getValue(),beginDate, endDate}, Double.class);
		//WAP端债权转让金额
		double creditor_transfer_price_wap = jt.queryForObject(UserSqlConstants.GET_CREDITOR_TRANSFER_PRICE, 
				new Object[] { UserEnums.Channel.WAP.getCode(),beginDate, endDate}, Double.class);

		try {
			jt.update(UserSqlConstants.INSERT_WAP_USER_DATA, staticsDate,register_count_wap,rechagre_count_wap,
					invest_count_wap,recharge_price_wap,invest_price_wap,wap_first_rech_amount, wap_first_invest_amount,
					login_count_wap,borrow_price_wap,creditor_transfer_price_wap, InvestChannelEnum.WAP.getValue(),wap_first_rech_amount_all,wap_first_invest_amount_all);
		} catch (Exception e) {
			logger.info("批量处理插入失败，处理sql:"
					+ UserSqlConstants.INSERT_WAP_USER_DATA + "处理数据:"
					+ beginDate + "错误信息:" + e);
		}

		//微信端注册人数
		int weixin_register_count = jt.queryForObject(UserSqlConstants.GET_REGISTER_USER_COUNT,
				new Object[] { beginDate, endDate,UserEnums.Channel.WEIXIN.getCode() }, Integer.class);

		//微信端首次充值人数
		int weixin_first_rech_amount = jt.queryForObject(UserSqlConstants.get_first_charge_count(OrderChannel.WEIXIN),
				new Object[] {beginDate, endDate }, Integer.class);

		//微信端首次投资人数
		int weixin_first_invest_amount = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT,
				new Object[] { UserEnums.Channel.WEIXIN.getCode(),NONE_USER_CHANNEL, InvestChannelEnum.WEIXIN.getValue(),beginDate, endDate }, Integer.class);
		
		//微信端首次充值人数(不区注册分客户端)
		int weixin_first_rech_amount_all = jt.queryForObject(UserSqlConstants.get_first_charge_count_all(OrderChannel.WEIXIN),
				new Object[] {beginDate, endDate }, Integer.class);

		//微信端首次投资人数(不区注册分客户端)
		int weixin_first_invest_amount_all  = jt.queryForObject(UserSqlConstants.GET_FIRST_INVEST_COUNT_ALL,
				new Object[] {  InvestChannelEnum.WEIXIN.getValue(),beginDate, endDate }, Integer.class);
		
		//微信端登录人数
		int login_count_weixin = jt.queryForObject(UserSqlConstants.GET_LOGIN_USER_COUNT, 
				new Object[] {beginDate, endDate, UserEnums.Channel.WEIXIN.getCode()}, Integer.class);
		//微信端充值用户数
		int rechagre_count_weixin = jt.queryForObject(UserSqlConstants.get_charge_count(OrderChannel.WEIXIN),
				new Object[] {beginDate, endDate}, Integer.class);
		//微信端投资用户数
		int invest_count_weixin = jt.queryForObject(UserSqlConstants.GET_INVEST_COUNT, 
				new Object[] { InvestChannelEnum.WEIXIN.getValue(),beginDate, endDate,InvestChannelEnum.WEIXIN.getValue(),beginDate, endDate}, Integer.class);
		//微信端充值金额
		double recharge_price_weixin = jt.queryForObject(UserSqlConstants.get_charge_price(OrderChannel.WEIXIN),
				new Object[] {beginDate, endDate}, Double.class);
		//微信端投资金额
		double invest_price_weixin = jt.queryForObject(UserSqlConstants.GET_INVEST_PRICE, 
				new Object[] { InvestChannelEnum.WEIXIN.getValue(),beginDate, endDate, InvestChannelEnum.WEIXIN.getValue(),beginDate, endDate}, Double.class);
		//微信端投资项目金额
		double borrow_price_weixin = jt.queryForObject(UserSqlConstants.GET_BORROE_PRICE, 
				new Object[] { InvestChannelEnum.WEIXIN.getValue(),beginDate, endDate}, Double.class);
		//微信端债权转让金额
		double creditor_transfer_price_weixin = jt.queryForObject(UserSqlConstants.GET_CREDITOR_TRANSFER_PRICE, 
				new Object[] { UserEnums.Channel.WEIXIN.getCode(),beginDate, endDate}, Double.class);

		try {
			jt.update(UserSqlConstants.INSERT_WAP_USER_DATA, staticsDate,weixin_register_count,rechagre_count_weixin,
					invest_count_weixin,recharge_price_weixin,invest_price_weixin,weixin_first_rech_amount, weixin_first_invest_amount,
					login_count_weixin,borrow_price_weixin,creditor_transfer_price_weixin, InvestChannelEnum.WEIXIN.getValue(),weixin_first_rech_amount_all,weixin_first_invest_amount_all);
		} catch (Exception e) {
			logger.info("批量处理插入失败，处理sql:"
					+ UserSqlConstants.INSERT_WAP_USER_DATA + "处理数据:"
					+ beginDate + "错误信息:" + e);
		}

	}

}
